package ch.zbw.timeline.service;

import java.util.ArrayList;
import java.util.List;

import ch.zbw.timeline.domain.Allocation;
import ch.zbw.timeline.domain.DailyPresence;
import ch.zbw.timeline.domain.Employee;
import ch.zbw.timeline.domain.Entry;
import ch.zbw.timeline.domain.OverTimePool;
import ch.zbw.timeline.repository.AllocationRepository;
import ch.zbw.timeline.repository.DailyPresenceRepository;
import ch.zbw.timeline.repository.EntryRepository;
import ch.zbw.timeline.repository.OverTimePoolRepository;
import ch.zbw.timeline.repository.hibernate.HibernateAllocationRepository;
import ch.zbw.timeline.repository.hibernate.HibernateDailyPresenceRepository;
import ch.zbw.timeline.repository.hibernate.HibernateEntryRepository;
import ch.zbw.timeline.repository.hibernate.HibernateOverTimePoolRepository;

/**
 * Class that implements the interface OverTimePoolService to handle the
 * overTimePools
 * 
 * @author Marco Ramseyer
 * @version 23.12.2011
 * 
 */
public class ZbwOverTimePoolService implements OverTimePoolService {

	private OverTimePoolRepository overTimePoolRepository;
	private EntryRepository entryRepository;
	private DailyPresenceRepository dailyPresenceRepository;
	private AllocationRepository allocationRepository;

	/**
	 * Default constructor without parameters initiates the
	 * overTimePoolRepository, entryRepository, dailyPresenceRepository,
	 * allocationRepository
	 */
	public ZbwOverTimePoolService() {
		overTimePoolRepository = new HibernateOverTimePoolRepository();
		entryRepository = new HibernateEntryRepository();
		dailyPresenceRepository = new HibernateDailyPresenceRepository();
		allocationRepository = new HibernateAllocationRepository();

		// overTimePoolRepository = new MockOverTimePoolRepository();
		// entryRepository = new MockEntryRepository();
		// dailyPresenceRepository = new MockDailyPresenceRepository();
		// allocationRepository = new MockAllocationRepository();
	}

	/**
	 * Constructor with parameters initiates a new overTimePoolServicerepository
	 * 
	 * @param overTimePoolServiceRepository
	 */
	public ZbwOverTimePoolService(OverTimePoolRepository overTimePoolServiceRepository) {
		this.overTimePoolRepository = overTimePoolServiceRepository;
	}

	/*
	 * (non-Javadoc)
	 * @see ch.zbw.timeline.service.OverTimePoolService#createOverTimePool(ch.zbw.timeline.domain.Employee, double, java.lang.String)
	 */
	@Override
	public OverTimePool createOverTimePool(Employee employee, double hours, String description) {

		OverTimePool overTimePoolLocalVariab = new OverTimePool();
		overTimePoolLocalVariab.setEmployeeFk(employee.getId());
		overTimePoolLocalVariab.setEmployee(employee);
		overTimePoolLocalVariab.setNumberOfHours(hours);
		overTimePoolLocalVariab.setDescription(description);

		List<OverTimePool> tmpList = overTimePoolRepository.getAllOverTimePools();
		boolean notExists = true;

		for (int i = 0; i < tmpList.size(); i++) {
			if (tmpList.get(i).equals(overTimePoolLocalVariab)) {
				notExists = false;
			}
		}

		if (notExists) {
			return overTimePoolRepository.saveOverTimePool(overTimePoolLocalVariab);
		}
		return null;
	}

	/*
	 * (non-Javadoc)
	 * @see ch.zbw.timeline.service.OverTimePoolService#saveOverTimePool(ch.zbw.timeline.domain.OverTimePool)
	 */
	@Override
	public OverTimePool saveOverTimePool(OverTimePool overTimePool) {

		double anzVerbrauchterStd = 0;
		Employee employee = overTimePool.getEmployee();

		List<DailyPresence> listPresenceTmp = dailyPresenceRepository.getAllDailyPresences(employee);

		for (int i = 0; i < listPresenceTmp.size(); i++) {

			List<Entry> listEntryTmp = entryRepository.getAllEntries(listPresenceTmp.get(i).getId());

			if (listEntryTmp != null) {
				for (int c = 0; c < listEntryTmp.size(); c++) {
					if (listEntryTmp.get(c).getOvertimePoolFk().equals(employee.getOverTimePoolFk())) {
						anzVerbrauchterStd += listEntryTmp.get(c).getDuration();
					}
				}
			}
		}
		
		if (anzVerbrauchterStd > overTimePool.getNumberOfHours()) {
			return null;
		} else {
			return overTimePoolRepository.saveOverTimePool(overTimePool);
		}
	}

	/*
	 * (non-Javadoc)
	 * @see ch.zbw.timeline.service.OverTimePoolService#getAllOverTimePools()
	 */
	@Override
	public List<OverTimePool> getAllOverTimePools() {
		return overTimePoolRepository.getAllOverTimePools();
	}

	/*
	 * (non-Javadoc)
	 * @see ch.zbw.timeline.service.OverTimePoolService#getOverTimePool(ch.zbw.timeline.domain.Employee)
	 */
	@Override
	public OverTimePool getOverTimePool(Employee employee) {
		return overTimePoolRepository.getOverTimePoolByEmployeeId(employee.getId());
	}

	/*
	 * (non-Javadoc)
	 * @see ch.zbw.timeline.service.OverTimePoolService#getOverTimePoolAllocations(ch.zbw.timeline.domain.Employee)
	 */
	@Override
	public List<Allocation> getOverTimePoolAllocations(Employee employee) {

		List<Allocation> listAllocations = new ArrayList<Allocation>();

		List<DailyPresence> listPresenceTmp = dailyPresenceRepository.getAllDailyPresences(employee);

		List<Allocation> listAllocationsToSearchForFk = allocationRepository.getAllAllocation();

		for (int i = 0; i < listPresenceTmp.size(); i++) {

			List<Entry> listEntryTmp = entryRepository.getAllEntries(listPresenceTmp.get(i).getId());

			if (listEntryTmp != null) {
				for (int c = 0; c < listEntryTmp.size(); c++) {
					if (listEntryTmp.get(c).getOvertimePoolFk() != null) {
						if (listEntryTmp.get(c).getOvertimePoolFk().equals(employee.getOverTimePoolFk())) {
							int tmp = listEntryTmp.get(c).getAllocationFk();

							for (int a = 0; a < listAllocationsToSearchForFk.size(); a++) {
								if (listAllocationsToSearchForFk.get(a).getId() == tmp) {

									boolean exists = false;
									for (int t = 0; t < listAllocations.size(); t++) {
										if (listAllocationsToSearchForFk.get(a).equals(listAllocations.get(t))) {
											exists = true;
										}
									}
									if (exists == false) {
										listAllocations.add(listAllocationsToSearchForFk.get(a));
									}
								}
							}
						}
					}
				}
			}
		}
		return listAllocations;
	}

	/*
	 * (non-Javadoc)
	 * @see ch.zbw.timeline.service.OverTimePoolService#getOverTimePoolHoursUsed(ch.zbw.timeline.domain.Employee)
	 */
	@Override
	public double getOverTimePoolHoursUsed(Employee employee) {

		double anzVerbrauchterStd = 0;

		List<DailyPresence> listPresenceTmp = dailyPresenceRepository.getAllDailyPresences(employee);

		for (int i = 0; i < listPresenceTmp.size(); i++) {

			List<Entry> listEntryTmp = entryRepository.getAllEntries(listPresenceTmp.get(i).getId());

			if (listEntryTmp != null) {
				for (int c = 0; c < listEntryTmp.size(); c++) {
					if (listEntryTmp.get(c).getOvertimePoolFk() != null) {
						if (listEntryTmp.get(c).getOvertimePoolFk().equals(employee.getOverTimePoolFk())) {
							anzVerbrauchterStd += listEntryTmp.get(c).getDuration();
						}
					}
				}
			}
		}
		return anzVerbrauchterStd;
	}
}
